﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IdentitiesScreen.cs" company="">
//   
// </copyright>
// <summary>
// Shows the available profiles to play.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

/*
 * Author: Juan Mompean Esteban
 * Created: 6-12-2011
 */
namespace ITU_vs_Zombies.Menu.Screens
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;

    using ITU_vs_Zombies.Character;
    using ITU_vs_Zombies.Game;
    using ITU_vs_Zombies.Graphics;
    using ITU_vs_Zombies.UsersInfo;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;

    /// <summary>
    /// Shows the available profiles to play.
    /// </summary>
    public class IdentitiesScreen : GameScreen
    {
        #region Constants and Fields

        /// <summary>
        /// The cols of one screen.
        /// </summary>
        private const int Cols = 4;

        /// <summary>
        /// The rows of one screen.
        /// </summary>
        private const int Rows = 3;

        /// <summary>
        /// The background texture.
        /// </summary>
        private Texture2D backgroundTexture;

        /// <summary>
        /// The content.
        /// </summary>
        private ContentManager content;

        /// <summary>
        /// The last write.
        /// </summary>
        private DateTime lastWrite;

        /// <summary>
        /// The matrix with all the profiles.
        /// </summary>
        private MatrixContainer matrix;

        /// <summary>
        /// A dictionary containing the name and the avatar of each profile.
        /// </summary>
        private Dictionary<string, string> profiles;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="IdentitiesScreen"/> class.
        /// </summary>
        public IdentitiesScreen()
        {
            this.profiles = new Dictionary<string, string>();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// The activate.
        /// </summary>
        /// <param name="instancePreserved">
        /// The instance preserved.
        /// </param>
        public override void Activate(bool instancePreserved)
        {
            if (instancePreserved)
            {
                return;
            }

            if (this.content == null)
            {
                this.content = new ContentManager(this.ScreenManager.Game.Services, "Content");
            }

            this.lastWrite = Directory.GetLastWriteTime(Profiles.Path);
            this.UpdateProfiles();
        }

        /// <summary>
        /// The draw.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        public override void Draw(GameTime gameTime)
        {
            Viewport viewport = this.ScreenManager.GraphicsDevice.Viewport;
            var fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);
            this.ScreenManager.SpriteBatch.Begin();
            this.ScreenManager.SpriteBatch.Draw(this.backgroundTexture, fullscreen, Color.White);
            this.matrix.Draw(viewport.Width, viewport.Height, this.ScreenManager.SpriteBatch);
            this.ScreenManager.SpriteBatch.End();
        }

        /// <summary>
        /// The enter pressed.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        public void EnterPressed(string name)
        {
            var player = new Player(
                100, @"Players\" + this.profiles.First(profile => profile.Key.Equals(name)).Value, 8, name);
            Client.MainPlayer = player;
        }

        /// <summary>
        /// The handle input.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        /// <param name="input">
        /// The input.
        /// </param>
        public override void HandleInput(GameTime gameTime, InputState input)
        {
            var escape = new InputAction(new[] { Keys.Escape }, true);
            var cKey = new InputAction(new[] { Keys.C }, true);

            this.matrix.Move(input);

            if (cKey.Evaluate(input))
            {
                this.ScreenManager.AddScreen(new CreateIdentityScreen());
            }

            if (!escape.Evaluate(input))
            {
                return;
            }

            this.ExitScreen();
        }

        /// <summary>
        /// The unload.
        /// </summary>
        public override void Unload()
        {
            this.backgroundTexture.Dispose();
            this.matrix.Dispose();
            this.content.Unload();
        }

        /// <summary>
        /// The update.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        /// <param name="otherScreenHasFocus">
        /// The other screen has focus.
        /// </param>
        /// <param name="coveredByOtherScreen">
        /// The covered by other screen.
        /// </param>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            if (this.lastWrite.CompareTo(Directory.GetLastWriteTime(Profiles.Path)) < 0)
            {
                this.lastWrite = Directory.GetLastWriteTime(Profiles.Path);
                this.UpdateProfiles();
            }

            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
        }

        #endregion

        #region Methods

        /// <summary>
        /// The update profiles.
        /// </summary>
        private void UpdateProfiles()
        {
            this.profiles = Profiles.LoadProfiles();

            this.backgroundTexture = this.content.Load<Texture2D>(@"background");
            var list = new List<Tuple<string, Texture2D>>(this.profiles.Count);
            list.AddRange(
                from profile in this.profiles
                let texture = this.content.Load<Texture2D>(@"Profiles\" + profile.Value)
                select new Tuple<string, Texture2D>(profile.Key, texture));

            this.matrix = new MatrixContainer(list, Rows, Cols);
            this.matrix.LoadContent(this.content);
            this.matrix.EnterPressed += this.EnterPressed;
        }

        #endregion
    }
}